#ifndef MOVEOPERA_H
#define MOVEOPERA_H

#include <BMap>

#include "Opera.h"

class TransOpera : public Opera
{
public:
	TransOpera(BNode* node)
	{
		_node = node;
		_origin = node->matrix();
	}

	void setMatrix(const BMatrix& matrix)
	{
		_matrix = matrix;
	}
	const BMatrix& matrix() const
	{
		return _matrix;
	}

	const BMatrix& origin() const
	{
		return _origin;
	}

	virtual BNode* node()
	{
		return _node;
	}
	virtual bool redo()
	{
		if (!_node)
			return false;
		_node->setMatrix(_matrix);
		emit("transformed", _node);
		return true;
	}
	virtual bool undo()
	{
		if (!_node)
			return false;
		_node->setMatrix(_origin);
		emit("transformed", _node);
		return true;
	}

private:
	BNode*		_node;
	BMatrix		_matrix;
	BMatrix		_origin;
};

class MultipleTransOpera : public Opera
{
public:
	MultipleTransOpera(const BNodeSet& nodes)
	{
		_nodes = nodes;
		for (int i = 0; i < nodes.size(); i++)
		{
			BNode* node = nodes[i];
			_originMap[node] = node->matrix();
		}
	}

	void setMatrix(BNode* node, const BMatrix& matrix)
	{
		_matrixMap[node] = matrix;
	}
	const BMatrix& matrix(BNode* node) const
	{
		return _matrixMap(node);
	}

	const BMatrix& origin(BNode* node) const
	{
		return _originMap(node);
	}

	virtual const BNodeSet& nodes()
	{
		return _nodes;
	}
	virtual bool redo()
	{
		if (_nodes.empty())
			return false;
		for (int i = 0; i < _nodes.size(); i++)
		{
			BNode* node = _nodes[i];
			const BMatrix& matrix = _matrixMap[node];
			node->setMatrix(matrix);
		}
		return true;
	}
	virtual bool undo()
	{
		if (_nodes.empty())
			return false;
		for (int i = 0; i < _nodes.size(); i++)
		{
			BNode* node = _nodes[i];
			const BMatrix& matrix = _originMap[node];
			node->setMatrix(matrix);
		}
		return true;
	}

private:
	BNodeSet				_nodes;
	BMap<BNode*, BMatrix>	_matrixMap;
	BMap<BNode*, BMatrix>	_originMap;
};

#endif